package hyl.ext.ws.msg;

import java.util.ArrayList;
import java.util.List;

import com.alibaba.fastjson2.JSON;
import com.alibaba.fastjson2.JSONObject;

import hyl.core.AIni;
import hyl.core.MyFun;
import hyl.core.fun.MyByte;
import hyl.core.run.IDo1;

/**
 * 
 * 历史消息对象  只适用于 字符串消息
 * 
 * 发送方和接收方 是 String 类型
 * 
 * 可以连续解析多次,适用于从文件中读取
 * 
 * 只适用于 websocket 不适用于socket
 * 
 * websocket 底层已经处理了粘包 拆包,收到的包都是完整的
 * 
 * 
 * 
 * @author 37798955@qq.com
 *
 */
public class WsMsgS implements Cloneable {
	@Override
	protected Object clone() throws CloneNotSupportedException {
		return super.clone();
	}

//为什么原来没有时间和发送方?
	public String 发送方;
	public String 接收方;
	public String 主题;
	public String 关键字;
	public String 时间;
	public String 内容;
	protected static WsMsgS wmpress = new WsMsgS();

	/**
	 * 
	 * @param 发送方 如果为0 表示是系统发送的
	 * @return
	 */
	public static WsMsgS getInstance(String 发送方) {
		try {
			WsMsgS wmp = (WsMsgS) wmpress.clone();
			wmp.set发送方(发送方);
			return wmp;
		} catch (CloneNotSupportedException e) {
			e.printStackTrace();
			return null;
		}
	}

	public void set发送方(String 发送方) {
		this.发送方 = 发送方;
	}

	public void setMsg(String 接收方, String 内容) {
		this.接收方 = 接收方;
		this.内容 = 内容;
		this.时间 = MyFun.getNow();
	}

	public void setMsg(String 发送方, String 接收方, String 主题, String 内容) {
		this.发送方 = 发送方;
		setMsg(接收方, 主题, 内容);
	}

	public void setMsg(String 接收方, String 主题, String 内容) {
		this.主题 = 主题;
		setMsg(接收方, 内容);
	}

	public void ini(String json) {
		JSONObject jo = JSON.parseObject(json);
		this.发送方 = jo.getString("发送方");
		this.接收方 = jo.getString("接收方");
		this.时间 = jo.getString("时间");
		this.主题 = jo.getString("主题");
		this.关键字 = jo.getString("关键字");
		this.内容 = jo.getString("内容");
	}

	public String toSendString() {
		return JSON.toJSONString(this);

	}

	/**
	 * 返回编译的字节
	 * 
	 * 用于保存到文件
	 * 
	 * @return
	 */
	public byte[] encode() {
		int i[] = new int[7];
		byte[] b1 = MyFun.str2Bytes(发送方, AIni.charset);
		byte[] b2 = MyFun.str2Bytes(接收方, AIni.charset);
		byte[] b3 = MyFun.str2Bytes(时间, AIni.charset);
		byte[] b4 = MyFun.str2Bytes(主题, AIni.charset);
		byte[] b5 = MyFun.str2Bytes(内容, AIni.charset);
		byte[] b6 = MyFun.str2Bytes(关键字, AIni.charset);
		i[1] = (b1 == null ? 0 : b1.length);
		i[2] = (b2 == null ? 0 : b2.length);
		i[3] = (b3 == null ? 0 : b3.length);
		i[4] = (b4 == null ? 0 : b4.length);
		i[5] = (b5 == null ? 0 : b5.length);
		i[6] = (b6 == null ? 0 : b6.length);
		i[0] = 4 * 6 + i[1] + i[2] + i[3] + i[4] + i[5] + i[6];//4*5 i[0]不含 头4
		return MyFun.concat(MyFun.int2ByteArray(i[0]), MyFun.int2ByteArray(i[1]), //
				MyFun.int2ByteArray(i[2]), MyFun.int2ByteArray(i[3]), //
				MyFun.int2ByteArray(i[4]), MyFun.int2ByteArray(i[5]), //
				b1, b2, b3, b4, b5, b6);

	}

	protected byte[] 剩余字节 = null;

	/**
	 * 
	 * @param data
	 * @return 返回 false 表示未结束 true 表示结束了
	 */
	public boolean decode(byte[] data) {
		if (data == null || data.length == 0) {
			剩余字节 = null;
			return true;
		}
		if (4 > data.length) {
			剩余字节 = data;
			return true;
		}
		int len = MyByte.bytes2int(data, 0);
		if (len > data.length) {
			剩余字节 = data;
			return true;
		}

		int i[] = new int[5];
		int start = 4;
		for (int j = 0; j < 5; j++) {
			i[j] = MyByte.bytes2int(data, start);
			start += 4;
		}
		发送方 = MyFun.bytes2U8str(MyByte.subBytes(data, start, i[0]));
		start += i[0];
		接收方 = MyFun.bytes2U8str(MyByte.subBytes(data, start, i[1]));
		start += i[1];
		时间 = MyFun.bytes2U8str(MyByte.subBytes(data, start, i[2]));
		start += i[2];
		主题 = MyFun.bytes2U8str(MyByte.subBytes(data, start, i[3]));
		start += i[3];
		内容 = MyFun.bytes2U8str(MyByte.subBytes(data, start, i[4]));
		start += i[4];
		int i6 = len - start;
		关键字 = MyFun.bytes2U8str(MyByte.subBytes(data, start, i6));
		start += i6;
		剩余字节 = MyByte.subBytes(data, len);
		return false;
	}

	/**
	 * 从本地文本中取出数据到 List中
	 * 
	 * @param data
	 * @return
	 */
	public static List<WsMsgS> loadMsgs(byte[] data) {
		List<WsMsgS> li = new ArrayList<>();
		while (true) {
			WsMsgS wmMsg = new WsMsgS();
			if (wmMsg.decode(data))
				return li; // 如果结束就退出
			li.add(wmMsg);		
			data = wmMsg.剩余字节;
		}
	}
	public static List<String> loadMsgjson(byte[] data) {
		List<String> li = new ArrayList<>();
		while (true) {
			WsMsgS wmMsg = new WsMsgS();
			if (wmMsg.decode(data))
				return li; // 如果结束就退出
			li.add(wmMsg.toSendString());		
			data = wmMsg.剩余字节;
		}
	}

	public static void foreach(byte[] data, IDo1<WsMsgS> 读取) {	
		while (true) {
			WsMsgS wmMsg = new WsMsgS();
			if (wmMsg.decode(data))
				return ; // 如果结束就退出
			读取.run(wmMsg);		
			data = wmMsg.剩余字节;
		}
	}
}
